<template>
  <div id="editMain" class="EditMain" ref="filecont" v-show="hasCurrentNote">
<!--    划词弹窗   -->
    <ul @mousedown.stop v-show="visiblemenu" :style="{ left: position.left + 'px', top: position.top + 'px'}" class="contextmenu">
      <el-container>
        <el-aside width="90px">
          <el-scrollbar height="200px">
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px" @click="abstract(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <EditPen />
              </el-icon>
              <span style="vertical-align: middle"> 概括 </span>
            </el-button>
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="polish(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <Brush />
              </el-icon>
              <span style="vertical-align: middle"> 润色 </span>
            </el-button>
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="expand(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <Postcard />
              </el-icon>
              <span style="vertical-align: middle"> 续写 </span>
            </el-button>
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="translate(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <CopyDocument />
              </el-icon>
              <span style="vertical-align: middle"> 翻译 </span>
            </el-button>
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="table(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <Crop />
              </el-icon>
              <span style="vertical-align: middle"> 表格 </span>
            </el-button>
            <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="segment(hisstring)">
              <el-icon style="vertical-align: middle" :size="16">
                <ScaleToOriginal />
              </el-icon>
              <span style="vertical-align: middle"> 分段 </span>
            </el-button>
          </el-scrollbar>
        </el-aside>
        <el-container v-show="contentDisplayerVisible">
          <el-main>
            <el-scrollbar height="120px" ref="scrollbarRef">
              <div style="width: 250px;font-size: 13px">
                {{ aiText }}
              </div>
            </el-scrollbar>
          </el-main>
          <el-footer height="40px" v-show="editButtonVisible">
            <div style="display: flex;flex-direction: row">
              <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 0" @click="insert(aiText)">
                <el-icon style="vertical-align: middle" :size="16">
                  <Edit />
                </el-icon>
                <span style="vertical-align: middle"> 插入 </span>
              </el-button>
              <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 3px" @click="replace(aiText)">
                <el-icon style="vertical-align: middle" :size="16">
                  <Switch />
                </el-icon>
                <span style="vertical-align: middle"> 替换 </span>
              </el-button>
              <el-button @mousedown.stop plain class="contextMenuButton" style="border-radius: 10px;margin-left: 3px" @click="notsee()">
                <el-icon style="vertical-align: middle" :size="16">
                  <Close />
                </el-icon>
                <span style="vertical-align: middle"> 取消 </span>
              </el-button>
            </div>
          </el-footer>
        </el-container>
      </el-container>
    </ul>

<!--    模板库弹窗    -->
    <el-dialog v-model="dialogTemplateVisible" width="800" title="智能模版库" style="border-radius: 10px; "
               :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" align-center>
      <template-dialog  @select="handleSelect"/>
      <template #footer>
        <el-button plain @click="dialogTemplateVisible=false;" :icon="Close">取消</el-button>
        <el-button type="primary" @click="dialogTemplateVisible=false;" :icon="Check">确定</el-button>
      </template>
    </el-dialog>

<!--    OCR弹窗    -->
    <el-dialog v-model="dialogOCRVisible" width="800" title="OCR图像识别" style="border-radius: 10px; "
               :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" align-center>
      <div>
        <el-container>
          <el-aside width="180px">
            <el-scrollbar height="400px" style="margin-left: 15px">
              <div style="font-size: 20px;font-weight: bold;color: #292929;margin-bottom: 15px">
                选择图片
              </div>
              <div style="display: flex;flex-direction: column">
                <el-upload
                    :on-success="handleSuccess"
                    list-type="picture-card"
                    :auto-upload="false"
                    :on-change="handleChanges"
                    :before-remove="beforeRemove"
                    :on-preview="handlePictureCardPreview"
                    :file-list="fileList "
                    multiple
                    limit="2"
                    name="img"
                    accept="image/*"
                >
                  <el-icon class="avatar-uploader-icon">
                    <Plus />
                  </el-icon>
                </el-upload>
                <el-button :loading="ocrLoading" style="margin-top: 10px;margin-left: auto;margin-right: 15px" :icon="Position" :disabled="fileList.length<1" @click="getOCR">
                  提取文字
                </el-button>
              </div>
            </el-scrollbar>
          </el-aside>
          <el-divider direction="vertical" style="height: 400px;margin-left: 0"/>
          <el-container>
            <el-header height="30px">
              <div style="font-size: 20px;font-weight: bold;color: #292929">
                图像识别结果
              </div>
            </el-header>
            <el-main style="margin-top: 0" v-loading="ocrLoading" element-loading-text="正在识别中，请稍后...">
              <el-scrollbar height="320px">
                <div style="font-size: 16px;width: 500px;align-content: flex-end">
                  {{(OCRText==""?"当前内容为空，请选择图片并进行图像识别。":OCRText)}}
                </div>
              </el-scrollbar>
            </el-main>
          </el-container>
        </el-container>
        <el-dialog v-model="dialogVisible">
          <img w-full class="imageshow" :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </div>
      <template #footer>
        <el-button plain @click="dialogOCRVisible=false;" :icon="Close">取消</el-button>
        <el-button type="primary" @click="copyOCRResult();fileList=[];OCRText=''" :icon="Check" :disabled="!hasOCRText">复制结果</el-button>
      </template>
    </el-dialog>

<!--    编辑器部分    -->
    <div class="editor">
      <div class="editor-card" >
        <div class="top-tools">
          <EditorMenu :editor="editor" :open-o-c-r="openOCRDialogue" :open-template-dialogue="openTemplateDialogue" :saved="!saved"/>
        </div>
        <div class="edit-cont" >
          <EditorContent
              @scroll="hasScroll()"
              @mousedown="notsee()"
              @mousemove="mousemove()"
              @mouseup="selecttext($event)"
              style="padding: 8px;  overflow-y: scroll; height: 100%"
              :editor="editor"
          />
        </div>

        <div class="bottom-count">
          <div style="margin-left: 10px;width: 200px">
            字数统计:
            {{ editor?.storage.characterCount.characters() }}
          </div>
          <div>
            |  正在编辑：{{currentNoteBook}}->{{noteInEditor.name}}
          </div>
        </div>
      </div>
    </div>

    <div class="right-tools" id="rightDrawer">
      <Outline style="height: 100%" ref="outLineRef" @collapse="toggleRight"></Outline>
    </div>
  </div>
  <div v-show="!hasCurrentNote">
    <!--    添加笔记的对话框      -->
    <el-dialog id="add-dialog"
               v-model="addNoteDialogVisible"
               title="新建笔记"
               :align-center="true"
               style="max-width: 420px;">
      <template #default>
        <el-row>
          <el-col :span="8" style="justify-content: end; display: flex; align-items: center">
            <div>笔记本：</div>
          </el-col>
          <el-col :span="12">
            <el-select v-model="selectedNotebook" value-key="id" placeholder="请选择笔记本" style="width: 100%">
              <el-option v-for="item in currentNotebooks" :key="item.id" :label="item.name" :value="item">
                <div style="display: flex; align-items: center">
                  <notebook class="icon" theme="multi-color" size="18" :fill="['#333' ,'#40afa0' ,'#FFF']"/>
                  <div style="margin-left: 5px; font-size: 16px">{{item.name}}</div>
                </div>
              </el-option>
            </el-select>
          </el-col>
        </el-row>
        <el-row style="margin-top: 5%">
          <el-col :span="8" style="justify-content: end; display: flex; align-items: center">
            <span>新笔记的名称：</span>
          </el-col>
          <el-col :span="12">
            <el-input v-model="addNoteInput" style="width: 100%"/>
          </el-col>
        </el-row>
      </template>
      <template #footer>
        <el-button @click="cancelAddNote">取消</el-button>
        <el-button type="primary" @click="addNote">确认</el-button>
      </template>
    </el-dialog>
    <!--模板库对话框-->
    <el-dialog v-model="dialogTemplateVisible2" width="800" title="智能模版库" style="border-radius: 10px; "
               :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" align-center>
      <template-dialog v-on:select="templateSelected"/>
      <template #footer>
        <el-button plain @click="dialogTemplateVisible2=false; cancelAddNote()" :icon="Close">取消创建</el-button>
        <el-button type="primary" @click="templateSelected('')" :icon="ArrowRight">跳过模板</el-button>
      </template>
    </el-dialog>
    <div style="display: flex;flex-direction: column;justify-content: center;align-items: center; height: 90vh;width: 130vh">
      <h1 style="color: gray;text-align: center">
        当前尚未选择笔记，请打开笔记本选择笔记
      </h1>
      <h1 style="color: gray;text-align: center">
        或选择新建笔记：
      </h1>
      <div class="addBtn" @click="addNoteDialogVisible=true">
        <el-icon size="25"><DocumentAdd /></el-icon>
        <div style="font-size: 20px;font-weight: bold">新建笔记</div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { currentNote, currentUser , currentNotebooks ,setCurrentNote} from "../../global"

import {
  ArrowRight,
  Brush, Check, Close, CopyDocument, Crop, DocumentAdd, Edit,
  EditPen, FullScreen,
  MagicStick, Plus, Position, Postcard, ScaleToOriginal, Switch,
} from '@element-plus/icons-vue'
import {onMounted, ref, watchEffect, onBeforeUnmount, watch, computed} from 'vue';
import { EditorContent, Editor  } from '@tiptap/vue-3';
import templateDialog from "@/components/TemplateDialog.vue"
// 列表
import ListItem from '@tiptap/extension-list-item'
import OrderedList from '@tiptap/extension-ordered-list'
import BulletList from '@tiptap/extension-bullet-list'
// 代码
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
import { common, createLowlight } from 'lowlight'
// 字数统计
import CharacterCount from '@tiptap/extension-character-count'
import StarterKit from '@tiptap/starter-kit'
import Placeholder from '@tiptap/extension-placeholder'
import TaskItem from '@tiptap/extension-task-item'
import TaskList from '@tiptap/extension-task-list'
import Outline from './Outline/index.vue'
import Table from '@tiptap/extension-table'
import TableCell from '@tiptap/extension-table-cell'
import TableHeader from '@tiptap/extension-table-header'
import TableRow from '@tiptap/extension-table-row'
import HighLight from '@tiptap/extension-highlight'
import { Extension } from '@tiptap/core'
import { globalEventBus } from '@/util/eventBus'
// 使用Pinia
import { useEditorStore } from '@/store'
import EditorMenu from './EditorMenu/index.vue'
import {Action, ElMessage, ElScrollbar} from 'element-plus';
import { streamPolishAPI, streamGenerateTableAPI, streamGetAbstractAPI, streamGetExpandAPI, streamGetSegmentAPI, streamTranslateAPI } from '@/api/ai';
import { getNoteAPI, updateNoteAPI, getNotebookByNoteId, addNoteAPI } from '@/api/note'
import { uploadImgAPI, imgOcrAPI } from "@/api/ocr.js"
import {TextAlign} from "@tiptap/extension-text-align";
import Image from '@tiptap/extension-image';

const hasCurrentNote = computed(() => {
  return currentNote.value.noteId !== -1
})

const lowlight = createLowlight()
lowlight.register({ html, ts, css, js })

const filecont = ref(null);
const visiblemenu = ref(false)
const editButtonVisible = ref(false)
const contentDisplayerVisible = ref(false)
const saved = ref(true)
const position = ref({
  top: 0,
  left: 0
})
const aiText = ref("")
var hasmove=ref(false);
var hisstring:any;
var selection:any;

const outLineRef = ref();

const noteInEditor = ref({
    notebookId: -1,
    noteId: -1,
    name: "",
    content: ""
})
const currentNoteBook = ref();

const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()

// OCR对话框
const dialogOCRVisible = ref(false);
const ocrLoading = ref(false)
const openOCRDialogue=()=>{
  dialogOCRVisible.value=true;
}
const OCRText = ref("");
const hasOCRText = computed(() => {
  return OCRText.value.length > 0
})

const getOCR = ()=>{
  OCRText.value = ""
  ocrLoading.value = true
  imgOcrAPI(ocrDir.value)
      .then((response) => {
        response.texts.forEach(text => OCRText.value += text)
        ocrLoading.value = false
      })
}

import useClipboard from 'vue-clipboard3'
const { toClipboard } = useClipboard()
const handleCopy = async () => {
  try {
    await toClipboard(OCRText.value)
    ElMessage.success("结果复制成功")
    console.log('复制成功')
  } catch (e) {
    ElMessage.error("复制失败")
    console.error(e);
    console.error('复制失败')
  }
}
const copyOCRResult = ()=>{
  dialogOCRVisible.value=false;
  handleCopy()
  // navigator.clipboard.writeText(OCRText.value).then(() => {
  //   ElMessage.success("结果复制成功")
  // }).catch((error) => {
  //   console.error('Failed to copy: ', error);
  // });
}
const addNoteDialogVisible = ref(false);
const selectedNotebook = ref(""); // 新建笔记时选择的笔记本
const addNoteInput = ref("");  // 新建笔记的名称
// 模板库对话框
const dialogTemplateVisible = ref(false);

const openTemplateDialogue=()=>{
  dialogTemplateVisible.value=true;
}
const handleSelect = async (templateContent) => {
  ElMessageBox.confirm(
      '使用新模板将会替换现有笔记的所有内容，请先做好备份后再继续。该行为可以撤回。是否继续？',
      '提示',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(() => {
        editor.commands.setContent(templateContent)
        saved.value = false
        dialogTemplateVisible.value = false
        ElMessage({
          type: 'success',
          message: '模板替换成功',
        })
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '已取消',
        })
      })
}

//新建笔记对话框
const cancelAddNote = () => {
  addNoteInput.value = "";
  addNoteDialogVisible.value = false;
  selectedNotebook.value = "";
}
const addNote = async () => {
  addNoteDialogVisible.value = false;
  const notebook = selectedNotebook.value;
  const newNoteName = addNoteInput.value;
  if (notebook === "") {
    ElMessage.error("请选择笔记本！");
    return;
  }
  if (newNoteName === "") {
    ElMessage.error("请输入新笔记本的名称！");
    return;
  }
  dialogTemplateVisible2.value = true
}
const dialogTemplateVisible2 = ref(false);
const templateSelected = async (templateContent) => {
  const notebook = selectedNotebook.value;
  const newNoteName = addNoteInput.value;
  const data = {
    "userid": currentUser.value.id,
    "name": newNoteName,
    "content": templateContent,
    "notebookid": notebook["id"]
  }
  dialogTemplateVisible2.value = false
  await addNoteAPI(data)
      .then((response) => {
        ElMessage.success("创建成功")
        setCurrentNote(response.id, response.name, notebook["id"])
      })
      .catch((err) => {
        ElMessage.error(err.response.data.message)
      })
  addNoteInput.value = "";
  addNoteDialogVisible.value = false;
  selectedNotebook.value = "";
}

document.addEventListener('mousedown', function(event) {
  let clickedTarget = event.target.className
  if (clickedTarget == 'buttonItem') {
    return
  }
  notsee();
});
document.addEventListener('keydown', function(event) {
  if(event.key=="s" && event.ctrlKey){
    event.preventDefault()
    event.returnValue = false
  }
});

watch(() => currentNote.value.noteId, (note, prevNote) => {
    console.log(note)
    if (prevNote > 0 && note === -1) {
      editor.clear()
      noteInEditor.value = { notebookId: -1, noteId: -1, name: "", content:""}
      return
    }
      
    if (note === -1)
        return
    if (noteInEditor.value.noteId !== -1) {
        noteInEditor.value.content = editor.getHTML()
        updateNoteAPI(noteInEditor.value).then().catch((err) => console.log(err))
    }
    getNoteAPI(note)
        .then((note) => {
            if (editor) {
                editor.commands.setContent(note.content)
                noteInEditor.value = note
              loadHeadings()
              editorStore.setEditorInstance(editor)
            }
        })
        .catch((err) => console.log(err))
      getNotebookByNoteId(currentNote.value.noteId)
          .then((notebook) => {
            currentNoteBook.value = notebook.name
          })
          .catch((err) => console.log(err))
},
{
    immediate: true
})

const CustomExtension = Extension.create({
    addCommands: () => {
        return {
            getSelectedText: () => ({ editor }) => {
                const { from, to, empty } = editor.state.selection
                currentFrom = from
                currentTo = to
                if (empty) {
                    return ''
                }

                return editor.state.doc.textBetween(from, to, ' ')
            },
            saveNote: () => ({ editor }) => {
                saveNote()
            }
            
        }
    },
    addKeyboardShortcuts() {
    return {
      // ↓ your new keyboard shortcut
      'Control-s': () => editor?.commands.saveNote(),
    }
  },
})

/*ai功能*/
function abstract(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamGetAbstractAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)
}

function polish(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamPolishAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)
}

function segment(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamGetSegmentAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)
}

function expand(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamGetExpandAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)
}


function table(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamGenerateTableAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)
}

function translate(text) {
  contentDisplayerVisible.value = true;
  editButtonVisible.value = false;
  streamTranslateAPI()
      .withDataHandler((msg) => { setTextBuffer(msg) })
      .withErrorHandler((err) => { errorHandler(err) })
      .withEndHandler(() => {editButtonVisible.value = true})
      .send(text)

}

/*context处理*/
function scrollToBottom() {
  scrollbarRef.value!.setScrollTop(scrollbarRef.value.wrapRef.clientHeight);
}

function insert(content) {
  if (editor) {
    editor.commands.insertContent(window.getSelection().toString() + content)
    visiblemenu.value = false;
    window.getSelection().collapseToEnd()
  }
}

function saveNote() {
  console.log('saveNote')
  var note = noteInEditor.value
  note.content = editor.getHTML()
  updateNoteAPI(note)
      .then((msg) => {
        ElMessage.success('成功保存笔记')
        saved.value = true
      })
      .catch((err) => { ElMessage.error('保存笔记失败'); console.log(err) })
}

function replace(content) {
  if (editor) {
    editor.commands.insertContentAt({currentFrom, currentTo}, content, {
      updateSelection: true
    })
    visiblemenu.value = false;
  }
}

function setTextBuffer(msg) {
  aiText.value = msg;
  scrollToBottom()
}

function errorHandler(err) {
  console.log(err)
}

// 获取选中的文字
const selecttext= (e:MouseEvent)=>{
  selection = window.getSelection();
  if(selection!=null&&hisstring!=selection){
    var content = selection.toString();
    if(content!=""){
      var rect = filecont.value.getBoundingClientRect();
      visiblemenu.value = true
      // alert(e.clientY)
      // alert(e.clientX)
      position.value.top =  e.clientY-60;
      position.value.left = e.clientX-120;
      hisstring=content
    }
  }
  else{
    hisstring=""
  }
}

//鼠标移动
const mousemove=()=>{
  hasmove.value=true;
}

//鼠标点击
const notsee=()=>{
  visiblemenu.value = false;
  editButtonVisible.value = false;
  contentDisplayerVisible.value = false;
  aiText.value = "";
  // selection.value="";
}

//滚轮滚动
const hasScroll=()=>{
  visiblemenu.value = false;
}

const editorStore = useEditorStore()

// 加载headings
const loadHeadings = () => {
  const headings = [] as any[]
  if (!editor) return
  const transaction = editor.state.tr
  if (!transaction) return

  editor.state.doc.descendants((node, pos) => {
    if (node.type.name === 'heading') {
      console.log(pos, node)
      const start = pos
      const end = pos + node.content.size
      // const end = pos + node
      const id = `heading-${headings.length + 1}`
      if (node.attrs.id !== id) {
        transaction?.setNodeMarkup(pos, undefined, {
          ...node.attrs,
          id
        })
      }

      headings.push({
        level: node.attrs.level,
        text: node.textContent,
        start,
        end,
        id
      })
    }
  })

  transaction?.setMeta('addToHistory', false)
  transaction?.setMeta('preventUpdate', true)

  editor.view.dispatch(transaction)
  editorStore.setHeadings(headings)
}

onMounted(() => {
  var loadContent = ''
  if (currentNote.value.noteId !== -1) {
      getNoteAPI(currentNote.value.noteId)
      .then((note) => {
          loadContent = note.content.toString()
          noteInEditor.value = note
      })
      .catch((err) => console.log(err))
      getNotebookByNoteId(currentNote.value.noteId)
          .then((notebook) => {
            currentNoteBook.value = notebook.name
          })
          .catch((err) => console.log(err))
  }else{
    ElMessage.info("目前还没有选择笔记")
  }

  editor.commands.setContent(loadContent)
})

onBeforeUnmount(() => {
  globalEventBus.all.clear()
  if (noteInEditor.value.noteId !== -1 && saved.value==false) {
    ElMessageBox.confirm(
        '检测到还未保存笔记，是否保存？',
        '提示',
        {
          confirmButtonText: '保存',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )
        .then(() => {
          saveNote()
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: '取消更改',
          })
        })
    // const confirmed = window.confirm('检测到还未保存笔记，是否保存？');
    // if (confirmed) {
    //   saveNote()
    // }
  }
  editor?.destroy()
})

// 使用ref创建可变的响应式引用
// 编辑器初始化
var currentFrom = 0
var currentTo = 0

const editor = new Editor({
  content: ``,
  extensions: [
    StarterKit.configure({
      heading: {
        levels: [1, 2, 3,4,5],
      },
    }),
    CustomExtension,
    TaskList,
    TaskItem,
    Placeholder.configure({
      placeholder: '开始输入文本 …'
    }),
    OrderedList,
    BulletList,
    ListItem,
    CharacterCount.configure({
      limit: 10000
    }),
    TextAlign.configure({
      types: ['heading', 'paragraph']
    }),
    Image,
    HighLight,
    Table,
    TableCell,
    TableRow,
    TableHeader
  ],
  onUpdate({ edit }) {
    loadHeadings()
    editorStore.setEditorInstance(editor)
    saved.value = false;
  },
  onCreate({ edit }) {
    loadHeadings()
    editorStore.setEditorInstance(editor)
  },
  onFocus({ edit }) {
    loadHeadings()
    editorStore.setEditorInstance(editor)
  },
  injectCSS: false,
})

const rightVisible = ref(true);

const toggleRightVisibility = () => {
  rightVisible.value = !rightVisible.value;
};

const toggleRight = ()=>{
  toggleRightVisibility();
  const drawer = document.getElementById("rightDrawer");
  if (rightVisible.value) {
    // open
    outLineRef.value.setVisible();
    drawer.style.flexGrow = '2';
  } else {
    // close
    outLineRef.value.setUnVisible();
    drawer.style.flexGrow = '0';
  }
}

//ocr
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handlePictureCardPreview = (file: UploadFile) => {
  dialogImageUrl.value = file.url!
  dialogVisible.value = true
}

const boxdisplay = ref("show_box");
const ocrDir = ref("")
const fileList = ref([]);

const handleSuccess = () => {
  // 上传成功后，隐藏上传按钮
};

const handleChanges = img => {
  if(fileList.value.length>0){
    ElMessageBox.confirm(
        '一次只能识别一张图像，该操作会替换上一张图像，是否继续？',
        '提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )
        .then(() => {
          fileList.value = []
          fileList.value.push(img)
          uploadImgAPI(img.raw)
              .then((response) => {
                ocrDir.value = response.path
              })
        })
        .catch(() => {
          let temp = fileList.value[0]
          fileList.value = []
          fileList.value.push(temp)
          uploadImgAPI(temp.raw)
              .then((response) => {
                ocrDir.value = response.path
              })
          ElMessage({
            type: 'info',
            message: '已取消',
          })
        })
  }else{
    fileList.value = []
    fileList.value.push(img)
    uploadImgAPI(img.raw)
        .then((response) => {
          ocrDir.value = response.path
        })
  }
};

import {ElMessageBox} from 'element-plus'
// 删除
const beforeRemove = () => {
  const result = new Promise((resolve, reject) => {
    ElMessageBox.confirm("此操作将删除该图片, 是否继续?", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    })
        .then(() => {
          boxdisplay.value = "show_box";
          fileList.value = [];
          OCRText.value = "";
        })
        .catch(() => {
          reject(false);
        });
  });
  return result;
};

</script>

<style>
.EditMain{
  width:100%;
  height: 100%;
  display: flex;
  padding: 10px 0 0 10px;
  box-sizing: border-box;
}

.right-tools{
  height: 100%;
  flex-grow: 2;
  flex-shrink: 0;
  max-width: 300px;
  margin-left: 5px;
  background-color: white;
  box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.3);
  border-radius: 15px;
}

.editor{
  height: 100%;
  flex: 8;
  display: flex;
  flex-direction: column;
}

.editor-card{
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid #4f5c5765;
  border-radius: 15px;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.1);
}

.editor-card .editor{
  width:100%;
  height: 100%;
}

.top-tools{
  background-color: rgba(207, 220, 245, 0.199);
  border-bottom: 1px dashed #9ca19f65;
  padding-top: 4px;
  padding-bottom: 1px;
  padding-left: 6px;
}

.bottom-count{
  display: flex;
  flex-direction: row;
  background-color: rgba(207, 220, 245, 0.199);
  border-top: 1px dashed #9ca19f65;
  width: 100%;
  padding-bottom: 3px;
  padding-top: 3px;
}

.edit-cont{
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

::-webkit-scrollbar{
  display: none;
}
</style>

<style lang="scss">
b {
  font-weight: bold;
}
.ProseMirror {
  overflow-y: scroll;
}
.ProseMirror p {
  margin: 0;
}
.ProseMirror:focus {
  outline: none;
}
.tiptap p.is-editor-empty:first-child::before {
  color: #adb5bd;
  content: attr(data-placeholder);
  float: left;
  height: 0;
  pointer-events: none;
}

.tiptap {
  > * + * {
    margin-top: 0.75em;
  }

  ul {
    padding: 0 2rem;
    list-style: square;
  }
  ol {
    padding: 0 2rem;
    list-style: decimal;
  }
  img {
    display: block;
    height: auto;
    margin: 1.5rem 0;
    max-width: 100%;

    &.ProseMirror-selectednode {
      outline: 3px solid var(--purple);
    }
  }
  table {
    border-collapse: collapse;
    table-layout: fixed;
    width: 100%;
    margin: 0;
    overflow: hidden;

    td,
    th {
      min-width: 1em;
      border: 2px solid #ced4da;
      padding: 3px 5px;
      vertical-align: top;
      box-sizing: border-box;
      position: relative;

      > * {
        margin-bottom: 0;
      }
    }

    th {
      font-weight: bold;
      text-align: left;
      background-color: #f1f3f5;
    }

    .selectedCell:after {
      z-index: 2;
      position: absolute;
      content: '';
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background: rgba(200, 200, 255, 0.4);
      pointer-events: none;
    }

    .column-resize-handle {
      position: absolute;
      right: -2px;
      top: 0;
      bottom: -2px;
      width: 4px;
      background-color: #adf;
      pointer-events: none;
    }

    p {
      margin: 0;
    }
  }
  pre {
    background: #0d0d0d;
    color: #fff;
    font-family: 'JetBrainsMono', monospace;
    padding: 0.75rem 1rem;
    border-radius: 0.5rem;

    code {
      color: inherit;
      padding: 0;
      background: none;
      font-size: 0.8rem;
    }

    .hljs-comment,
    .hljs-quote {
      color: #616161;
    }

    .hljs-variable,
    .hljs-template-variable,
    .hljs-attribute,
    .hljs-tag,
    .hljs-name,
    .hljs-regexp,
    .hljs-link,
    .hljs-name,
    .hljs-selector-id,
    .hljs-selector-class {
      color: #f98181;
    }
    .hljs-number,
    .hljs-meta,
    .hljs-built_in,
    .hljs-builtin-name,
    .hljs-literal,
    .hljs-type,
    .hljs-params {
      color: #fbbc88;
    }

    .hljs-string,
    .hljs-symbol,
    .hljs-bullet {
      color: #b9f18d;
    }

    .hljs-title,
    .hljs-section {
      color: #faf594;
    }

    .hljs-keyword,
    .hljs-selector-tag {
      color: #70cff8;
    }

    .hljs-emphasis {
      font-style: italic;
    }

    .hljs-strong {
      font-weight: 700;
    }
  }
}

.tableWrapper {
  overflow-x: auto;
}

.resize-cursor {
  cursor: ew-resize;
  cursor: col-resize;
}
.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding:5px;
  border-radius: 15px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 1px 1px 2px 1px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  gap: 0;
}
.contextmenu .buttonItem {
  height: 35px;
  width: 70px;
  line-height: 35px;
  color: rgb(29, 33, 41);
  cursor: pointer;
  border-radius: 10px;
  margin: 0;
  margin-left: 15px;
  box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.05);
}
//.contextmenu .buttonItem {
//  height: 35px;
//  width:100%;
//  line-height: 35px;
//  color: rgb(29, 33, 41);
//  cursor: pointer;
//}

.contextmenu .buttonItem:hover {
  background: rgb(229, 230, 235);
}


:-webkit-any(article,aside,nav,section)
:-webkit-any(article,aside,nav,section) h1 {
  font-size: 2em;
  margin-block-start: 0.67em;
  margin-block-end: 0.67em;
}
.contextMenuButton {
  border-radius: 10px;
  margin-left: 0;
  margin-bottom: 5px;
}
.addBtn {
  border: 4px dashed rgb(160, 160, 160);
  border-radius: 10px;
  margin: 10px 10% 0 10%;
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  color: rgb(160, 160, 160);
  padding: 10px;
  width: 120px;
}
.addBtn:hover {
  background-color: rgb(240,240,240, 0.5);
}
</style>
